function bci=bciTrainOddball(bci,T)

doDebug = ~true;
doWindsorize = ~true;
doScale = true;
featSelectMethod='svm';%'swlr';%'rsqu';
selectFeat = 64; % number of channels or fraction of raw features
maxTrainSampPerClass=333;

% manipulate T to get a two class representation of target/non-target

% reshape back to trial X channel X feature 
tmpDat = reshape(T.dat,[size(T.dat,1),bci.reshape.reSize]);

% windsorize, normalize; see Hoffmann et al., 2008, JNeurosciMeth 167
if doWindsorize||doScale,
    % reshape back to channel X timepoint X trial
    x = permute(tmpDat,[2 3 1]);
    if doWindsorize,
        bci.windsor = windsor;
        bci.windsor = train(bci.windsor,x,0.1);
        x = apply(bci.windsor,x);
    end
    if doScale,
        bci.normZscore = normalize;
        bci.normZscore = train(bci.normZscore,x,'z-score');
        x = apply(bci.normZscore,x);
    end        
    tmpDat=permute(x,[3 1 2]);
end

% some constants
nChan = size(tmpDat,2);
nTargets = length(bci.eventsToClassify);
nLabel = length(T.label);
nTFlashes = bci.paradigm.nTargetFlashes;

if selectFeat >= nChan,
    selectFeat = 0;
end

if bci.paradigm.doAverageFlashEvents,
    nFeat =  size(T.dat,2)/nChan/nTargets/2;
    nMFeat = size(T.dat,2)/nChan/2;

    % allocate memory
    newT.dat = zeros(size(T.dat,1)*2,nChan*nFeat);
    newT.label = zeros(size(T.dat,1)*2,1);
    if doDebug,
        targetMean=zeros(size(tmpDat,2),nFeat);
        nonTargetMean = zeros(size(tmpDat,2),nFeat);
    end
    for lab =1:nLabel,
        % get the target features
        targetIdx = (T.label(lab)-1)*nFeat +(1:nFeat);
        newT.dat(lab,:)=reshape(tmpDat(lab,:,targetIdx),[1,nChan*nFeat]);
        newT.label(lab)=bci.eventsToClassify(1); % use as pseudo two class label
        % get the non-target features
        newT.dat(lab+nLabel,:) = reshape(tmpDat(lab,:,targetIdx+nMFeat),[1,nChan*nFeat]);
        newT.label(lab+nLabel) = bci.eventsToClassify(2);
        if doDebug,
            targetMean=targetMean + squeeze(tmpDat(lab,:,targetIdx));
            nonTargetMean=nonTargetMean + squeeze(tmpDat(lab,:,targetIdx+nMFeat));
        end
    end
else
    nFlashes = nTFlashes*nTargets;
    nFeat =  size(T.dat,2)/nChan/nTargets/nTFlashes;
    nFeatPerTarget = size(T.dat,2)/nChan/nTargets;

    % allocate memory
    newT.dat = zeros(size(T.dat,1)*nFlashes,nChan*nFeat);
    newT.label = zeros(size(T.dat,1)*nTFlashes*nTargets,1);

    if doDebug,
        targetMean=zeros(size(tmpDat,2),nFeat);
        nonTargetMean = zeros(size(tmpDat,2),nFeat);
    end
    
    for lab =1:nLabel,
        % get the target features
        for flash = 1:nTFlashes,
            targetIdx = (T.label(lab)-1)*nFeatPerTarget +(flash-1)*nFeat+(1:nFeat);
            newT.dat((lab-1)*nFlashes+flash,:)=reshape(tmpDat(lab,:,targetIdx),[1,nChan*nFeat]);
            newT.label((lab-1)*nFlashes+flash)=bci.eventsToClassify(1); % use as pseudo two class label
            if doDebug,
                targetMean=targetMean + squeeze(tmpDat(lab,:,targetIdx));
            end
        end
        % get the non-target features
        remLab = setdiff(1:nTargets,T.label(lab));
        for rem = 1:length(remLab),
            for flash=1:nTFlashes,
                targetIdx = (remLab(rem)-1)*nFeatPerTarget +(flash-1)*nFeat+(1:nFeat);
                if doDebug,
                    nonTargetMean=nonTargetMean + squeeze(tmpDat(lab,:,targetIdx));
                end
                newT.dat((lab-1)*nFlashes+(rem)*nTFlashes+flash,:)=reshape(tmpDat(lab,:,targetIdx),[1,nChan*nFeat]);
                newT.label((lab-1)*nFlashes+(rem)*nTFlashes+flash)=bci.eventsToClassify(2); % use as pseudo two class label
            end
        end
    end
end

if doDebug,
    time = linspace(0,size(targetMean,2)/bci.param.resampFreq,size(nonTargetMean,2));
    targetMean=targetMean/sum(newT.label==1);
    nonTargetMean=nonTargetMean/sum(newT.label==2);
    limits = [min([targetMean(:);nonTargetMean(:)]),max([targetMean(:);nonTargetMean(:)])];
    figure; 
    subplot(2,1,1);
    plot(time,targetMean');
    ylim(limits);
    subplot(2,1,2);
    plot(time,nonTargetMean');    
    ylim(limits);
end

% by default, balance trainset, 
% bci.param.balanceTrainSet affects target object balancing, 
% not target vs non-target balancing 

label_bin = getBalancedTrainset(newT.label,maxTrainSampPerClass,'equal');
newT.label = newT.label(label_bin);
newT.dat = newT.dat(label_bin,:);

% select features; do not use bci.param.featSelect for oddball paradims
if ~isempty(featSelectMethod)&& selectFeat>0,
    W=bciCompareFeatures(newT.dat,newT.label, featSelectMethod, [], [1 2]);
    Wresh=reshape(W,[nChan,nFeat]);
    featureMask = false(size(Wresh));
    if selectFeat <1,
        [dummy sortIdx]=sort(abs(Wresh(:)),'descend');
        featureMask(sortIdx(1:round(selectFeat*nChan*nFeat)))=true;
    else        
        % determine maximum
        R2=max(abs(Wresh),[],2);
        [dummy sortIdx]=sort(R2,'descend');
        featureMask(sortIdx(1:selectFeat),:)=true;
    end
    bci.oddball.featureMask = featureMask(:);
    newT.dat=newT.dat(:,bci.oddball.featureMask);
else
    bci.oddball.featureMask = true(1,nFeat*nChan);
end

if strcmpi(bci.param.classifier,'logreg'),
    bci = bciTrainLogReg(bci,newT);
    bci.oddball.testFunc = str2func('bciTestLogReg');
elseif strcmpi(bci.param.classifier,'svm'),
    bci = bciTrainSVM(bci,newT);
    bci.oddball.testFunc = str2func('bciTestSVM');
elseif strcmpi(bci.param.classifier,'bayeslda'),
    bci = bciTrainBayesLDA(bci,newT);
    bci.oddball.testFunc = str2func('bciTestBayesLDA');
elseif strcmpi(bci.param.classifier,'rda'),
    bci = bciTrainRDA(bci,newT);
    bci.oddball.testFunc = str2func('bciTestRDA');
else
    error('classifier unknown');
end